import {Request} from "./request.js"
import {BlueUtils} from "./blue-utils.js"

export class BluePlus {

  constructor(state) {
    this.blueUtils = new BlueUtils()
    this.dataUtils = new DataUtils()
    this.request = new Request()
  }

  showToast(msg) {
    uni.showToast({title: msg})
  }

  async startBluetoothDiscovery() {
    await this.blueUtils.startBluetoothDevicesDiscovery({
      readyBack: async () => {//蓝牙准备就绪，请求接口，发送第一条bwnr
        console.log("startBluetoothDevicesDiscovery---readyBack")
        let bwnr = await this.request.firstRequest()
        console.log("<<<<<第1次请求报文内容", bwnr)
        if (bwnr) this.firstSendData(bwnr)
      },
      valueBack: async (e) => {
        console.error("3>>>startBluetoothDevicesDiscovery---valueBack", this.dataUtils.buffer2hex(e.value))
        if (e.value != undefined) this.receiveBlueValue(e)
      }
    })
  }

  /**
   * 接受到蓝牙的值并处理
   */
  async receiveBlueValue(e) {
    let {endFlag, value} = this.dataUtils.confirm4b(e.value)
    console.log("3.2>>>confirm4b---result", endFlag, value)
    if (value) await this.confirmSend(value)
    if (endFlag == '4b') {
      sendMsgStart++
      this.continueSend()
    } else if (endFlag == 'end') {
      let respData = receivedData.join('')
      receivedData = []
      if (respData != '') this.secondSendData(respData)
    } else if (endFlag == 'oneEnd') {
      return
    }
  }

  async secondSendData(respData) {
    console.log("<<<<<secondSendData=====value==", respData)
    if (respData != '' && respData != null) {
      if (this.judge_code(respData)) {
        console.log("sendMessage============receiveRightStr", receiveRightStr)
        let res = await this.request.circleRequest(receiveRightStr)
        bwnrJq = res.bwnr
        if (res.ywbsm) this.queryData(res)
      } else {
        console.log("sendMessage============bwList")
        const bwrnList = receiveRightStr.split('68')[1].substring(0, 2)
        if (bwrnList == '91') {
          let beTop = '68' + bwnrJq.split('68')[1]
          let bwFloor = '68' + receiveRightStr.split('68')[1]
          let bwList = beTop + bwFloor
          console.log('3次充值' + bwList)
          let res = await this.request.circleRequest(bwList)
          bwnrJq = res.bwnr
          if (res.ywbsm) this.queryData(res)
        } else {
          this.showToast("充值失败！")
        }
      }
    }
  }

  firstSendData(sendStr) {
    sendMsgArr = []
    sendMsgStart = 0
    for (let i = 0; i < sendStr.length; i = i + 34) {
      sendMsgArr.push(sendStr.substr(i, 34))
    }
    this.continueSend()
  }

  continueSend() {
    console.log("continueSend---sendMsgStart:" + sendMsgStart, "msgSendSize:" + sendMsgArr.length)
    if (sendMsgStart > sendMsgArr.length - 1) {
      console.log("continueSend---本次已经完成！")
      return
    }
    if (sendMsgBack) {
      sendMsgBack = false
      // 发送之前转换buffer
      let tranMsg = this.dataUtils.str2ab(sendMsgArr[sendMsgStart], sendMsgStart, sendMsgArr)
      console.log("【continueSend】---tranMsg", this.dataUtils.buffer2hex(tranMsg))
      this.blueUtils.writeValue(tranMsg)
    }
  }

  async confirmSend(secondBF) {
    let cbf = new ArrayBuffer(3)
    let dataView = new DataView(cbf)
    dataView.setUint8(0, 0x4b)
    let ctrl = secondBF | 0b00100000
    let ctrl16 = parseInt(ctrl, 10).toString(16)
    if (ctrl16.length == 1) {
      ctrl16 = '0' + ctrl16
    }
    dataView.setUint8(1, '0x' + ctrl16)
    dataView.setUint8(2, 0x00)
    console.log("【confirmSend】---tranMsg", secondBF, cbf)
    await this.blueUtils.writeValue(cbf)
  }

  judge_code(respData) {
    let strs = ''
    for (let j = 0; j < respData.length; j++) {
      strs += respData[j]
      if (j % 2 === 1) {
        strs += ','
      }
    }
    let ary = strs.split(',')
    for (let i = 0; i < ary.length; i++) {
      if (ary[i] == '68') {
        if (ary[i + 7] == '68' && ary[parseInt('0x' + ary[i + 9]) + 11 + i] == '16') {
          receiveRightStr = ary.slice(i, parseInt('0x' + ary[i + 9]) + 11 + i + 1)
          receiveRightStr = receiveRightStr.join('')
          console.log(receiveRightStr + '拼接')
          return true
        } else {
          continue
        }
      }
    }
    receiveRightStr = ary.slice().join('')
    console.log(receiveRightStr + '切除不完整报文')
    return false
  }

  /**
   * 查询结果
   */
  queryData = res => {
    //todo 处理页面逻辑
    if (res.ywbsm === '000104') {
      console.log('queryData---000104')
      this.firstSendData(res.bwnr)
    } else if (res.ywbsm === '500601') {
      console.log('queryData---500601')
      this.showToast("流程结束！")
    } else {
      console.log("?????????????queryData------------writeValue?????????????")
      this.blueUtils.writeValue(res.bwnr)
    }
  }
}

/**
 * Android设备和蓝牙设备数据交换过程：
 * 1.Android设备请求接口获取bwnr数据
 * 2.Android将bwnr分片依次发送到蓝牙设备【continueSend】，每次发送完成的标志：接受到蓝牙设备返回的【4b】标志
 * 3.蓝牙设备依次返回数据，Android先提取保存数据，再截取数据并发送回蓝牙设备【confirmSend】
 * ，最后蓝牙会返回结束标志后Android将保存的数据拼接发送到接口
 */
let sendMsgArr = [] //所有需要发送的数据，按长度不超17字节截取在这里
let sendMsgStart = 0 //发送消息时从哪一帧开始发送
let sendMsgBack = true //每次发送是否已经收到了返回消息
let receivedData = [] //从蓝牙返回的所有有用信息
let receiveRightStr = ""//从蓝牙返回的有用的信息
let bwnrJq = ""//接口使用的逻辑参数

export class DataUtils {
  str2ab(str, index, msgArr) {
    let strByteLen = str.length / 2
    let buf = new ArrayBuffer(strByteLen + 3)
    let dataView = new DataView(buf)
    dataView.setUint8(0, 0x4a) //0x4a
    dataView.setUint8(1, DataUtils.bit2ForHexadecimal(index, msgArr))
    //这里把长度转换成16进制数
    let hexStr = parseInt(strByteLen, 10).toString(16)
    if (hexStr.length == 1) {
      hexStr = '0' + hexStr
    }
    dataView.setUint8(2, '0x' + hexStr)
    for (let i = 0, strLen = str.length; i < strLen; i = i + 2) {
      let n = str.substr(i, 2)
      if (n.length == 1) {
        n = '0' + n
      }
      dataView.setUint8(i / 2 + 3, '0x' + n)
    }
    return buf
  }

  //生成控制字,index为第几帧数据，返回一个二时制的数据
  static bit2ForHexadecimal(index, msgArr) {
    let baseBit = 0b00000000
    let ctrlBit = 0
    let i = index + 1
    if (i == 1) {
      //如果第一帧，高位7为1，其它位为0；
      ctrlBit = 0b10000000
    }
    if (msgArr.length == i) {
      //如果是最后一帧，高位为0，bit6为1，最低帧为顺序加1
      ctrlBit = ctrlBit ^ (0b01000000 ^ (i - 1))
    } else {
      if (ctrlBit) {
        //如果第一帧的话，最低位要顺序加1
        ctrlBit = ctrlBit ^ (baseBit ^ (i - 1))
      } else {
        ctrlBit = baseBit ^ (i - 1)
      }
    }
    //ctrlBit会自动变成10进制
    //这里把10进制的ctrlBit转成16进制
    let ctrlBit16 = parseInt(ctrlBit, 10).toString(16)
    if (ctrlBit16.length < 2) {
      ctrlBit16 = '0x0' + ctrlBit16
    } else {
      ctrlBit16 = '0x' + ctrlBit16
    }
    return ctrlBit16
  }

  buffer2hex(buffer) {
    let hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    })
    return hexArr.join('')
  }

  confirm4b(value) {
    console.log("3.1>>>confirm4b---value2str", this.buffer2hex(value))
    let dataView = new DataView(value)
    let firstBF = dataView.getUint8(0)
    firstBF = parseInt(firstBF, 10).toString(16)
    firstBF = firstBF.toLocaleLowerCase()
    let secondBF = dataView.getUint8(1)
    //如果接收到的是4b确认帧
    if (firstBF.indexOf('4b') > -1) {
      sendMsgBack = true
      return {endFlag: '4b', value: null}
    } else {
      for (let i = 0; i < value.byteLength; i++) {
        if (i >= 3) {
          let bf = dataView.getUint8(i)
          let rbf = bf.toString(16)
          if (rbf.length == 1) {
            rbf = '0' + rbf
          }
          receivedData.push(rbf)
        }
      }
      //ctrl如果是以11 或 01 表示结束
      let binSecondBF = parseInt(secondBF, 10).toString(2)
      let binSecondBFLen = binSecondBF.length
      //如果少于8位，在前面补0
      if (binSecondBFLen < 8) {
        binSecondBF = '00000000'.substr(0, 8 - binSecondBFLen) + binSecondBF
      }
      let bit6 = binSecondBF.substr(1, 1)
      sendMsgBack = true
      //如果第6位是1表示传输结束
      if (bit6 == 1) {
        return {endFlag: 'end', value: secondBF}
      }
      return {endFlag: 'oneEnd', value: secondBF}
    }
  }
}
